<template>
  <canvas
    id="com-global-clock"
    style="width:100%;">当前浏览器不支持canvas，请更换浏览器后再试
  </canvas>
</template>

<script>
  /**
   * 时钟显示组件
   */
  export default {
    name: 'ComGlobalClock',
    data() {
      return {
        /**
         * 点数据
         */
        digit: [
          [
            [0, 0, 1, 1, 1, 0, 0],
            [0, 1, 1, 0, 1, 1, 0],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [0, 1, 1, 0, 1, 1, 0],
            [0, 0, 1, 1, 1, 0, 0]
          ], //0
          [
            [0, 0, 0, 1, 1, 0, 0],
            [0, 1, 1, 1, 1, 0, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [1, 1, 1, 1, 1, 1, 1]
          ], //1
          [
            [0, 1, 1, 1, 1, 1, 0],
            [1, 1, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 1, 1, 0, 0, 0],
            [0, 1, 1, 0, 0, 0, 0],
            [1, 1, 0, 0, 0, 0, 0],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 1, 1, 1, 1, 1]
          ], //2
          [
            [1, 1, 1, 1, 1, 1, 1],
            [0, 0, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 1, 1, 1, 0, 0],
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [0, 1, 1, 1, 1, 1, 0]
          ], //3
          [
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 1, 1, 1, 0],
            [0, 0, 1, 1, 1, 1, 0],
            [0, 1, 1, 0, 1, 1, 0],
            [1, 1, 0, 0, 1, 1, 0],
            [1, 1, 1, 1, 1, 1, 1],
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 1, 1, 1, 1]
          ], //4
          [
            [1, 1, 1, 1, 1, 1, 1],
            [1, 1, 0, 0, 0, 0, 0],
            [1, 1, 0, 0, 0, 0, 0],
            [1, 1, 1, 1, 1, 1, 0],
            [0, 0, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [0, 1, 1, 1, 1, 1, 0]
          ], //5
          [
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 1, 1, 0, 0, 0],
            [0, 1, 1, 0, 0, 0, 0],
            [1, 1, 0, 0, 0, 0, 0],
            [1, 1, 0, 1, 1, 1, 0],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [0, 1, 1, 1, 1, 1, 0]
          ], //6
          [
            [1, 1, 1, 1, 1, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 0, 1, 1, 0, 0, 0],
            [0, 0, 1, 1, 0, 0, 0],
            [0, 0, 1, 1, 0, 0, 0],
            [0, 0, 1, 1, 0, 0, 0]
          ], //7
          [
            [0, 1, 1, 1, 1, 1, 0],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [0, 1, 1, 1, 1, 1, 0],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [0, 1, 1, 1, 1, 1, 0]
          ], //8
          [
            [0, 1, 1, 1, 1, 1, 0],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [1, 1, 0, 0, 0, 1, 1],
            [0, 1, 1, 1, 0, 1, 1],
            [0, 0, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 0, 1, 1],
            [0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 1, 1, 0, 0],
            [0, 1, 1, 0, 0, 0, 0]
          ], //9
          [
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 1, 1, 1, 0, 0],
            [0, 0, 1, 1, 1, 0, 0],
            [0, 0, 1, 1, 1, 0, 0],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 1, 1, 1, 0, 0],
            [0, 0, 1, 1, 1, 0, 0],
            [0, 0, 1, 1, 1, 0, 0],
            [0, 0, 0, 0, 0, 0, 0]
          ] //:
        ],
        /**
         * 时间对象
         */
        oTimer: null,
        /**
         * 存储时间数据
         */
        timeData: [],
        /**
         * 存储运动的小球
         */
        balls: []
      }
    },
    props: {
      /**
       * 高度
       */
      h: {
        type: Number,
        default: 100
      },
      /**
       * 宽度
       */
      w: {
        type: Number,
        default: 700
      },
      /**
       * 设置粒子半径 canvas.height / 20 - 1
       */
      r: {
        type: Number,
        default: 4
      }
    },
    mounted() {
      this.creatClock ()
    },
    methods: {
      /**
       * 创建时钟
       */
      creatClock() {
        const canvas = document.getElementById ('com-global-clock')
        if (canvas.getContext) {
          const cxt = canvas.getContext ('2d')
          canvas.height = this.h
          canvas.width = this.w
          cxt.fillStyle = '#f00'
          cxt.fillRect (10, 10, 50, 50)
          const temp = /(\d)(\d):(\d)(\d):(\d)(\d)/.exec (new Date ())
          //存储时间数字，由十位小时、个位小时、冒号、十位分钟、个位分钟、冒号、十位秒钟、个位秒钟这7个数字组成
          this.timeData.push (temp[1], temp[2], 10, temp[3], temp[4], 10, temp[5], temp[6])

          clearInterval (this.oTimer)
          this.oTimer = setInterval (() => {
            //更新时钟
            this.updateDigitTime ()
            //更新小球状态
            this.updateBalls ()
            //渲染
            this.render (canvas, cxt)
          }, 50)
        }
      },
      /**
       * 生成点阵数字
       */
      renderDigit(cxt, index, num) {
        for (let i = 0; i < this.digit[num].length; i++) {
          for (let j = 0; j < this.digit[num][i].length; j++) {
            if (this.digit[num][i][j] == 1) {
              cxt.beginPath ()
              cxt.arc (
                14 * (this.r + 2) * index + j * 2 * (this.r + 1) + (this.r + 1),
                i * 2 * (this.r + 1) + (this.r + 1),
                this.r,
                0,
                2 * Math.PI
              )
              cxt.closePath ()
              cxt.fill ()
            }
          }
        }
      },
      /**
       * 渲染
       */
      render(canvas, cxt) {
        //重置画布宽度，达到清空画布的效果
        canvas.height = this.h
        //渲染时钟
        for (let i = 0; i < this.timeData.length; i++) {
          this.renderDigit (cxt, i, this.timeData[i])
        }
        //渲染小球
        for (let i = 0; i < this.balls.length; i++) {
          cxt.beginPath ()
          cxt.arc (this.balls[i].x, this.balls[i].y, this.r, 0, 2 * Math.PI)
          cxt.fillStyle = this.balls[i].color
          cxt.closePath ()
          cxt.fill ()
        }
      },
      /**
       * 更新时钟
       */
      updateDigitTime() {
        const changeNumArray = []
        const temp = /(\d)(\d):(\d)(\d):(\d)(\d)/.exec (new Date ())
        const NewData = []
        NewData.push (temp[1], temp[2], 10, temp[3], temp[4], 10, temp[5], temp[6])
        for (let i = this.timeData.length - 1; i >= 0; i--) {
          //时间发生变化
          if (NewData[i] !== this.timeData[i]) {
            //将变化的数字值和在data数组中的索引存储在changeNumArray数组中
            changeNumArray.push (i + '_' + ((Number (this.timeData[i]) + 1) % 10))
          }
        }
        //增加小球
        for (let i = 0; i < changeNumArray.length; i++) {
          this.addBalls.apply (this, changeNumArray[i].split ('_'))
        }
        this.timeData = NewData.concat ()
      },
      /**
       * 更新小球状态
       */
      updateBalls() {
        for (let i = 0; i < this.balls.length; i++) {
          this.balls[i].stepY += this.balls[i].disY
          this.balls[i].x += this.balls[i].stepX
          this.balls[i].y += this.balls[i].stepY
          if (this.balls[i].x > this.w + this.r || this.balls[i].y > this.h + this.r) {
            this.balls.splice (i, 1)
            i--
          }
        }
      },
      /**
       * 增加要运动的小球
       */
      addBalls(index, num) {
        const numArray = [1, 2, 3]
        const colorArray = [
          '#3BE',
          '#09C',
          '#A6C',
          '#93C',
          '#9C0',
          '#690',
          '#FB3',
          '#F80',
          '#F44',
          '#C00'
        ]
        for (let i = 0; i < this.digit[num].length; i++) {
          for (let j = 0; j < this.digit[num][i].length; j++) {
            if (this.digit[num][i][j] == 1) {
              const ball = {
                x: 14 * (this.r + 2) * index + j * 2 * (this.r + 1) + (this.r + 1),
                y: i * 2 * (this.r + 1) + (this.r + 1),
                stepX: Math.floor (Math.random () * 4 - 2),
                stepY: -2 * numArray[Math.floor (Math.random () * numArray.length)],
                color: colorArray[Math.floor (Math.random () * colorArray.length)],
                disY: 1
              }
              this.balls.push (ball)
            }
          }
        }
      }
    },
    /**
     * 对象销毁前调用
     */
    beforeDestroy() {
      clearInterval (this.oTimer)
    }
  }
</script>

<style lang="scss" scoped>
</style>
